<?php

namespace App\Http\Controllers\Logic;

use App\Exceptions\BusinessException;
use App\Helpers\ProjectHelper;
use App\Http\Controllers\Constant\Constant;
use App\Http\Controllers\Controller;
use App\Model\OAFiles;
use App\Model\OAPositionMapping;
use App\Model\OAProjectLx;
use App\Model\OAProjectYs;
use App\Model\OAProjectYsDetail;
use App\Model\OAShenPiLog;
use App\Model\OAWork;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;

class ProjectYsLogic extends Controller
{
    public static $work_id = OAWork::WORK_PROJECT_JS;

    //添加预算
    public function addProjectYs($params)
    {
        //dd($params);
        try {
            DB::beginTransaction();
            $xmid = $params['xmid'];
            $lx = OAProjectLx::query()->find($xmid);
            if(is_null($lx)) throw new \Exception("立项不存在");
            if(empty($params['ysid'])) $this->checkRepeatYs($xmid);
            $node_id = $this->getCurrentNode(self::$work_id,$params['roleid']);
            $is_save = $params['is_save'];
            $roleid = $params['roleid'];
            $status = 0;
            $ysData = $params['ysData'];
            $this->checkYsDataDetail($ysData);
            //如果提交
            if(!$is_save){
                $nextApprover = $this->getNextApprover($node_id,self::$work_id,Constant::PROJECT_STATUS_WAIT);
                $roleid = $nextApprover['roleid'];
                $node_id = $nextApprover['node_id'];
                $status = Arr::get($nextApprover,'status');
            }

            //添加预算详情数据
            $insert_data = [
                'xmid'=>$params['xmid'],
                'type'=>1,
                'uid'=>$params['uid'],
                'roleid'=>$roleid,
                'create_role'=>$params['roleid'],
                'is_save'=>$params['is_save'],
                'node_id'=>$node_id,
                'tax'=> str_replace(',','',$params['tax']),
                'total'=>str_replace(',','',$params['total']),
                'profit'=>str_replace(',','',$params['profit']),
                'percent'=>$params['percent'],
                'created_at'=>date('Y-m-d H:i:s'),
                'desc'=>$params['desc'] ?? '',
                'offer'=>resetMoney($params['ysmoney']),
                'cost'=>resetMoney($params['yscost']),
                'work_id'=>self::$work_id,
                'status' =>$status,
                'deptid'=>$lx->deptid,
                "sub_total"=>resetMoney(Arr::get($params,'sub_total','0.00')),
                "start"=>Arr::get($params,"start",""),
                "stop"=>Arr::get($params,"stop",""),
            ];

            if(isset($params['ysid']) && !empty($params['ysid'])){
                $ysid = $params['ysid'];
                $ys = OAProjectYs::find('id',$ysid);
                if($ys) $ys->fill($insert_data)->save();
            }else{
                $processLink = ProjectHelper::getRolesAndUidsByWorkIdAndGsId(self::$work_id,$lx->gsid);
                $insert_data = array_merge($insert_data,$processLink);
                $ys = OAProjectYs::create($insert_data);
                $ysid = $ys->id;
            }

            //预算详情
            $ysData = $params['ysData'];
            $this->handleYsDetailData($ysData,$ys);
            //文件
            $file_list = $params['fileList'];
            if($file_list) $this->saveFileList($ysid,$file_list,FILE_YS,self::$work_id);
            //检测修改记录
            $newData = [
                'id'=>$params['xmid'],
                'city'=>$params['city'],
                'currency'=>$params['currency'] ?? 'CNY',
            ];

            $logData = $this->checkDifferentData($newData,'lx');
            $logData = implode(';',$logData);
            $record = [
                'work_id' => self::$work_id,
                'uid' => $params['uid'],
                'roleid' => $params['roleid'],
                'id' => $ysid,
                'note' => $logData,
                'state' => 1,
            ];
            if($logData){
                   if(!$is_save)$this->saveShenPiLog($record);
                   OAProjectLx::query()->where('id',$newData['id'])->update($newData);
            }else{
                if(!$is_save && isPM()){
                    $record['note'] = '提交预算';
                    $this->saveShenPiLog($record);
                }
            }
            DB::commit();
            return $ysid;
        }catch (\Exception $e){
            DB::rollBack();
            throw new \Exception($e->getMessage());
        }

    }

    //检查预算是否存在
    public function checkRepeatYs($xmid,$type=1)
    {
        $isExists = OAProjectYs::query()->where(['xmid'=>$xmid,'type'=>$type])->exists();

        if($isExists) throw new \Exception('该项目已申请过,请勿重复申请');

    }

    //预算详情
    public function getProjectYsDetail(OAProjectYs $projectInfo,bool $isJs=false)
    {

        if($isJs){
            $where = ['ysid'=>$projectInfo->id];
        }else{
            $where = ['ysid'=>$projectInfo->id,'is_js'=>Constant::STATUS_OFF];
        }
        $ysData = OAProjectYsDetail::query()->where($where)->get()->toArray();
        $sub_total = '0.00';
        $disabled_role = config('oa.disableRole');
        foreach ($ysData as &$ys){
            if($ys['is_del']){
                $ys['disabled'] = true;
                $ys['isDel'] = false;
            }elseif(!in_array($ys['paytype'],[Constant::PAY_TYPE_FK,Constant::PAY_TYPE_BX])){
                $ys['disabled'] = false;
                $ys['isDel'] = false;
            }else{
                $ys['disabled'] = in_array(roleid(),$disabled_role) || roleid() != $projectInfo->roleid;
                $ys['isDel'] = !in_array(roleid(),$disabled_role) && roleid() == $projectInfo->roleid;
            }
            if($ys['is_js'] || $ys['paytype'] == Constant::PAY_TYPE_YJ || $ys['is_del']) continue;
            $sub_total = bcadd($sub_total,$ys['money'],2);
            $ys['money'] = fomateMoney("",$ys['money']);
        }
        //dd($ysData);
        // TCZ_REPO=http://mirrors.tuna.tsinghua.edu.cn/tinycorelinux/10.x/x86/tcz/
        $projectInfo->ysData = $ysData;
        $projectInfo->sub_total = fomateMoney("",$sub_total);
        $projectInfo->baseInfo = $this->getBaseInfo(['id'=>$projectInfo->xmid]);
        $log = new ApproveHistory();
        $projectInfo->history = $log->getApproveHistory($projectInfo);
        $projectInfo->file_list = $this->getFileList($projectInfo->id,FILE_YS);
        $projectInfo->spForm = OAShenPiLog::getTempSpFormData($projectInfo->work_id,$projectInfo->id);
        return $projectInfo;

    }

    //获取预算列表
    public function getProjectYsList($params)
    {

        $roleid = $params['roleid'];
        DB::enableQueryLog();
        $query = OAProjectYs::query();
        $list = $query
        ->status(Arr::get($params,'status',0))
        ->roles()

        ->when(isset($params['name']) && !empty($params['name']),function ($q) use ($params){
            return $q->where('name','like','%'.$params['name'].'%');
        })

        //立项人
        ->when(isset($params['create_user']) && !empty($params['create_user']),function ($q) use ($params){
            return $q->where('uid',$params['create_user']);
        })
        //日期
        ->when(isset($params['date']) && !empty($params['date']),function ($q) use ($params){
            return $q->whereBetween('start',$params['date']);
        })
        //类型
        ->when($type = Arr::get($params,'type',1),function ($q) use ($type){
            return $q->where('type',$type);
        })
        ->orderBy('created_at','DESC')
        ->latest("updated_at")
        ->paginate($params['page_size'],[
                'profit','percent','created_at','id','tax','total','offer','uid','xmid',
            ],'page')
        ->toArray();
        if ($list['data']) {
            $xmids = array_column($list['data'],'xmid');
            $lxList = OAProjectLx::query()->whereIn('id',$xmids)->select(['id','name','leader'])->get()->toArray();
            $lxList = array_column($lxList,null,'id');
            foreach ($list['data'] as &$val) {
                $val['name'] = Arr::get($lxList,sprintf("%s.name",$val['xmid']));
                $val['leader'] = Arr::get($lxList,sprintf("%s.leader",$val['xmid']));
            }
        }
        $list['sql'] = $query->toSql();
        $list['bindings'] = $query->getBindings();
        return $list;
    }

    //修改预算
    public function editProjectYs(Request $request, OAProjectYs $ysInfo)
    {
        try{
          DB::beginTransaction();
          $params = $request->all();
          $id = $params['id'];
          //修改预算数据
          $ysData = $params['ysData'];
          $this->checkYsDataDetail($ysData);
          $project = $params['project'];
          $ysLog = $this->checkDifferentData($params,'ys');
          $xmLog = $this->checkDifferentData($params['baseinfo'],'lx');
          $projectName = Arr::get($params,'baseinfo.name');
          if($xmLog && is_array($xmLog)){
              $this->saveBaseInfo($params['baseinfo']);//修改项目基础数据
          }
          $ysInfo->total = resetMoney($project['total']);
          $ysInfo->tax = resetMoney($project['tax']);
          $ysInfo->profit = resetMoney($project['profit']);
          $ysInfo->percent = $project['percent'];
          $ysInfo->desc = $project['desc'];
          $ysInfo->offer = resetMoney($project['offer']);
          $ysInfo->cost = resetMoney($project['cost']);
          $is_save = $request->input('is_save');
          //项目经理调整
          if(!$is_save && admin_id() == $ysInfo->uid){
              $nextApprover = $this->getNextApprover($ysInfo->node_id,$ysInfo->work_id,1);
              $ysInfo->node_id = $nextApprover['node_id'];
              $ysInfo->roleid = $nextApprover['roleid'];
              $ysInfo->status = Arr::get($nextApprover,'status');
          }
            //保存文件
            $this->saveFileList($id,Arr::get($params,'file_list'),FILE_YS,self::$work_id);
            $this->handleYsDetailData($ysData,$ysInfo);
            $xmLog = $xmLog && is_array($xmLog) ? $xmLog :  [];
            $ysLog = $ysLog && is_array($ysLog) ?$ysLog : [];
            $log = array_merge($ysLog,$xmLog);
          //修改记录
            if($log) {
                $logData = [
                    'note' => implode(';', $log),
                    'id' => $id,
                    'work_id' => $ysInfo->work_id,
                    'state' => 2,
                    'roleid' => $params['roleid'],
                    'uid' => $params['uid'],
                ];
                $this->saveShenPiLog($logData);
            }else{
                $isExists = OAShenPiLog::checkShenLogExists($ysInfo->work_id,$id);
                if($request->is_pm && !$isExists){
                    OAShenPiLog::createShenPiLogs($ysInfo->work_id,$id,sprintf('提交%s预算',$projectName));
                }
            }
          $ysInfo->is_save = $is_save;
          $ysInfo->save();

          //审批日志
            $spForm = Arr::get($params,'spForm',[]);
            if($spForm){
                $note = Arr::get($spForm,'note','无');
                $spLog = OAShenPiLog::createShenPiLogs(self::$work_id,$ysInfo->id,$note,OAShenPiLog::SHENPI_STATUS_NOTHING);
                $file_list = Arr::get($spForm,'fileList',[]);
                if($file_list) {
                    $this->saveFileList($spLog->id,$file_list,OAFiles::FILE_TYPE_TEMP,self::$work_id);
                }
            }
          DB::commit();
          return $ysInfo;
        }catch (\Exception $e){
            DB::rollBack();
            throw new \Exception($e->getMessage());
        }
    }

    //修改销售经理
    public function updateSeller(Request $request,OAProjectYs $ys){
        try{
            DB::beginTransaction();
            $approver = $ys->approver;
            $sellerId = $request->input('seller_id');
            if($ys->seller_id){
                $approver = array_map(function ($item) use ($ys){
                    return $item != $ys->seller_id;
                },$approver);
            }
            $approver[] = strval($sellerId);
            $ys->seller_id = $sellerId;
            $ys->approver = $approver;
            $ys->save();
            DB::commit();
            return true;
        }catch (\Exception $e){
            DB::rollBack();
            throw new \Exception($e->getMessage());
        }
    }

    //获取预算数据
    public function getYsData($params)
    {
        $data = OAProjectYsDetail::query()->where('ysid',$params['id'])->select(['id','title','money','desc','paytype'])->get()->toArray();
        if(empty($data)) return $data;
        foreach ($data as &$val){
            $val['isDel'] = false;
            $val['money'] = number_format($val['money'],2);
        }
        return $data;
    }

    protected function checkYsDataDetail($ysData)
    {
        $titles = [];
        foreach ($ysData as $val){
            $title = $val['title'];
            if(!Arr::get($val,'desc','')) throw new \Exception('请添加'.$title.'备注');
            if(in_array($title,$titles)) throw new BusinessException(sprintf("预算%s重复,请检查",$title));
            $titles[] = $title;
        }
    }


}
